﻿
#include "Matrix.h"

Matrix::Matrix()
{
    _width = 0;
    _height = 0;
    _type = 0;

    esMatrixLoadIdentity(&_resultMatrix);
    esMatrixLoadIdentity(&_viewMatrix);
    esMatrixLoadIdentity(&_scaleMatrix);
    esMatrixLoadIdentity(&_rotateMatrix);
    esMatrixLoadIdentity(&_moveMatrix);

    _isChange = false;
}

void Matrix::setViewSize(int width, int height)
{
    if (_width == width && _height == height)
    {
        return;
    }

    _width = width;
    _height = height;

    esMatrixLoadIdentity(&_viewMatrix);

    float w = width / 2;
    float h = height / 2;

    switch (_type)
    {
    case 0:
        // 正交矩阵
        esOrtho(&_viewMatrix, -w, w, -h, h, -100, 100);
        break;
    case 1:
        // 透视矩阵
        esPerspective(&_viewMatrix, 60, w / h, 1.0f, 2000.0f);
        break;
    default:
        esOrtho(&_viewMatrix, -w, w, -h, h, -100, 100);
        break;
    }

    _isChange = true;
}

void Matrix::setType(int type)
{
    _type = type;
    setViewSize(_width, _height);
}

void Matrix::setScale(float sx, float sy, float sz)
{
    esMatrixLoadIdentity(&_scaleMatrix);

    // 缩放矩阵
    esScale(&_scaleMatrix, sx, sy, sz);

    _isChange = true;
}

void Matrix::setRotate(float angle, float x, float y, float z)
{
    esMatrixLoadIdentity(&_rotateMatrix);

    // 旋转矩阵
    esRotate(&_rotateMatrix, angle, x, y, z);

    _isChange = true;
}

void Matrix::setMove(float x, float y, float z)
{
    esMatrixLoadIdentity(&_moveMatrix);

    // 位移矩阵
    esTranslate(&_moveMatrix, x, y, z);

    _isChange = true;
}

const ESMatrix& Matrix::getMatrix()
{
    if (!_isChange)
    {
        return _resultMatrix;
    }
    _isChange = false;

    esMatrixLoadIdentity(&_resultMatrix);

    // 绽放
    esMatrixMultiply(&_resultMatrix, &_scaleMatrix, &_resultMatrix);

    // 移动
    esMatrixMultiply(&_resultMatrix, &_moveMatrix, &_resultMatrix);

    // 旋转
    esMatrixMultiply(&_resultMatrix, &_rotateMatrix, &_resultMatrix);

    // 计算最终的MVP矩阵:模型视图矩阵和投影矩阵的乘积
    esMatrixMultiply(&_resultMatrix, &_resultMatrix, &_viewMatrix);

    return _resultMatrix;
}

bool Matrix::isChange()
{
    return _isChange;
}